#include "myfile.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <malloc.h>
#include <unistd.h>
#include <assert.h>

MY_FILE* my_fopen(const char* path,const char* mode)
{
  //1.识别标志位
  int flag=0;
  if(strcmp(mode,"r")==0)flag |= O_RDONLY;
  else if(strcmp(mode,"w")==0)flag |= (O_CREAT|O_WRONLY|O_TRUNC);
  else if(strcmp(mode,"a")==0)flag |= (O_CREAT|O_WRONLY|O_APPEND);
  else{
    //other operator
  }
  
  //2.尝试打开文件
  mode_t m = 0666;
  int fd = 0;
  if(flag&O_CREAT)fd = open(path,flag,m);
  else fd = open(path,flag);

  if(fd<0)return NULL;

  //3.给用户返回MY_FILE对象，需要先进行构建
  MY_FILE* mf = (MY_FILE*)malloc(sizeof(MY_FILE));
  if(mf == NULL){
    close(fd);
    return NULL;
  }

  //4.初始化MY_FILE对象
  mf->fd = fd;
  mf->flags = 0;
  mf->flags|=BUFF_LINE;
  memset(mf->outputbuffer,'\0',sizeof(mf->outputbuffer));
  mf->current=0;

  //5.返回打开的文件
  return mf;

}

int my_fflush(MY_FILE* fp){
  assert(fp);
  //将用户缓冲区中的数据，通过系统调用接口，冲刷给OS
  write(fp->fd,fp->outputbuffer,fp->current);
  fp->current=0;
  fsync(fp->fd);
  return 0;
}

size_t my_fwrite(const void* ptr,size_t size,size_t nmemb,MY_FILE* stream)
{
  //1.如果缓冲区已经满了，就直接写入
  if(stream->current==NUM)my_fflush(stream);

  //2.根据缓冲区剩余情况，进行数据拷贝即可
  size_t user_size = size*nmemb;
  size_t my_size = NUM - stream->current;

  size_t writen = 0;
  if(my_size>=user_size){
    memcpy(stream->outputbuffer+stream->current,ptr,user_size);
    //3.更新计数器字段
    stream->current += user_size;
    writen = user_size;
  }else{
    memcpy(stream->outputbuffer+stream->current,ptr,my_size);
    //3.更新计数器字段
    stream->current += my_size;
    writen = my_size;
  }

  if(stream->flags&BUFF_ALL)
  {
    if(stream->current==NUM)my_fflush(stream);
  }
  else if(stream->flags& BUFF_LINE)
  {
    if(stream->outputbuffer[stream->current-1]=='\n')my_fflush(stream);
  }
  else{

  }
  return writen;

}

int my_fclose(MY_FILE* fp)
{
  assert(fp);
  //冲刷缓冲区
  if(fp->current>0)my_fflush(fp);
  //关闭文件
  close(fp->fd);
  //释放空间
  free(fp);
  fp=NULL;
  return 0;
}







